<?php
/**
 * Created By PhpStorm
 * Author: patrick wu
 * Date: 2020/10/16
 * Time: 11:17
 */
namespace App\Service\Api;

use App\Http\Model\Mysql\UserBindModel;
use App\Http\Model\Mysql\UserModel;
use App\Http\Model\Mysql\OrderModel;
use App\Http\Model\Mysql\OrderProductModel;
use App\Http\Model\Mysql\OrderSupplyModel;
use App\Http\Model\Mysql\WechatNotifyModel;
use App\Http\Model\Mysql\UserMemberModel;
use App\Events\OrderFinish;
use App\Http\Model\Mysql\WechatOrderModel;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class NotifyService extends BaseService
{
    /**
     * 微信支付回调处理
     * @param array $notify_data
     * @return array
     */
    public function notifyPay(array $notify_data)
    {
        if ($notify_data['return_code'] != 'SUCCESS') {
            return [false, $notify_data['return_msg'] ?? '请求错误'];
        }

        $wechat_config = Config::get('wechat');

        //校验签名
        if ($notify_data['sign'] != wechatEncrypt($notify_data, $wechat_config['mch_key'])) {
            return [false, '签名校验错误'];
        }
        /**
         * 保存通知回调记录
         */
        $notify_log['appid']    =   $notify_data['appid'];
        $notify_log['mch_id']   =   $notify_data['mch_id'];
        $notify_log['device_info']  =   $notify_data['device_info'] ?? '';
        $notify_log['nonce_str']    =   $notify_data['nonce_str'];
        $notify_log['sign']         =   $notify_data['sign'];
        $notify_log['sign_type']    =   $notify_data['sign_type'] ?? 'MD5';
        $notify_log['result_code']  =   $notify_data['result_code'];
        $notify_log['err_code']     =   $notify_data['error_code'] ?? '';
        $notify_log['err_code_desc']=   $notify_data['error_code_desc'] ?? '';
        $notify_log['openid']       =   $notify_data['openid'];
        $notify_log['is_subscribe'] =   $notify_data['is_subscribe'];
        $notify_log['trade_type']   =   $notify_data['trade_type'];
        $notify_log['bank_type']    =   $notify_data['bank_type'];
        $notify_log['total_fee']    =   $notify_data['total_fee'];
        $notify_log['settlement_total_fee'] = $notify_data['settlement_total_fee'] ?? $notify_data['total_fee'];
        $notify_log['cash_fee']     =   $notify_data['cash_fee'];
        $notify_log['coupon_fee']   =   $notify_data['coupon_fee'] ?? 0;
        $notify_log['coupon_count'] =   $notify_data['coupon_count'] ?? 0;
        $notify_log['transaction_id'] = $notify_data['transaction_id'];
        $notify_log['out_trade_no'] =   $notify_data['out_trade_no'];
        $notify_log['attach']       =   $notify_data['attach'] ?? '';
        $notify_log['time_end']     =   $notify_data['time_end'];
        $notify_log['query_ip']     =   request()->getClientIp();
        WechatNotifyModel::create($notify_log);

        /**
         * 交易失败，放入失败队列中，等待处理
         */
        if ($notify_data['result_code'] != 'SUCCESS') {
            //processing
            return [false, '交易失败'];
        }

        /**
         * 查看用户信息
         */
        $user_info  =   UserModel::where(['openid' => $notify_data['openid']])->select(['uid', 'nickname', 'openid'])->first();

        /**
         * 查看订单信息
         */
        $order_info =   OrderModel::where(['order_no' => $notify_data['out_trade_no']])->select(['id', 'user_id', 'order_no', 'is_pay', 'pay_type', 'pay_time', 'pay_transaction', 'share_id'])->first();
        if (empty($order_info)) {
            return [false, '非法订单号'];
        }

        $pay_time   =   Carbon::createFromFormat('YmdHis', $notify_data['time_end'])->timestamp;
        /**
         * 交易成功，保存支付记录，更新订单支付
         */
        $order_info->is_pay     =   OrderModel::IS_PAY;
        $order_info->pay_type   =   1;
        $order_info->pay_time   =   $pay_time;
        $order_info->pay_transaction    =   $notify_data['transaction_id'];
        $order_info->save();

        if (!empty($order_info->supply)) {
            foreach ($order_info->supply as $item) {
                OrderSupplyModel::where(['id' => $item->id])->update(['supply_price' => DB::raw('supply_total')]);
                OrderProductModel::where(['order_supply_id' => $item->id])->update(['product_price' => DB::raw('product_total')]);
            }
        }

        /**
         * 触发订单结束事件 代理商返佣或者盒子返佣
         */
        event(new OrderFinish($order_info));
        return [true, '支付处理成功'];
    }

    /**
     * 会员开通支付回调处理
     * @param array $notify_data
     * @return array
     */
    public function notifyMember(array $notify_data)
    {
        if ($notify_data['return_code'] != 'SUCCESS') {
            return [false, $notify_data['return_msg'] ?? '请求错误'];
        }

        $wechat_config = Config::get('wechat');

        //校验签名
        if ($notify_data['sign'] != wechatEncrypt($notify_data, $wechat_config['mch_key'])) {
            return [false, '签名校验错误'];
        }
        /**
         * 保存通知回调记录
         */
        $notify_log['appid']    =   $notify_data['appid'];
        $notify_log['mch_id']   =   $notify_data['mch_id'];
        $notify_log['device_info']  =   $notify_data['device_info'] ?? '';
        $notify_log['nonce_str']    =   $notify_data['nonce_str'];
        $notify_log['sign']         =   $notify_data['sign'];
        $notify_log['sign_type']    =   $notify_data['sign_type'] ?? 'MD5';
        $notify_log['result_code']  =   $notify_data['result_code'];
        $notify_log['err_code']     =   $notify_data['error_code'] ?? '';
        $notify_log['err_code_desc']=   $notify_data['error_code_desc'] ?? '';
        $notify_log['openid']       =   $notify_data['openid'];
        $notify_log['is_subscribe'] =   $notify_data['is_subscribe'];
        $notify_log['trade_type']   =   $notify_data['trade_type'];
        $notify_log['bank_type']    =   $notify_data['bank_type'];
        $notify_log['total_fee']    =   $notify_data['total_fee'];
        $notify_log['settlement_total_fee'] =   $notify_data['settlement_total_fee'] ?? $notify_data['total_fee'];
        $notify_log['cash_fee']     =   $notify_data['cash_fee'];
        $notify_log['coupon_fee']   =   $notify_data['coupon_fee'] ?? 0;
        $notify_log['coupon_count'] =   $notify_data['coupon_count'] ?? 0;
        $notify_log['transaction_id']=  $notify_data['transaction_id'];
        $notify_log['out_trade_no'] =   $notify_data['out_trade_no'];
        $notify_log['attach']       =   $notify_data['attach'] ?? '';
        $notify_log['time_end']     =   $notify_data['time_end'];
        $notify_log['query_ip']     =   request()->getClientIp();
        WechatNotifyModel::create($notify_log);

        /**
         * 交易失败，放入失败队列中，等待处理
         */
        if ($notify_data['result_code'] != 'SUCCESS') {
            //processing
            return [false, '交易失败'];
        }

        /**
         * 修改用户会员购买记录
         */
        $member_info = UserMemberModel::where(['order_no' => $notify_data['out_trade_no']])->select(['id', 'user_id', 'order_no', 'member_price'])->first();
        if (empty($member_info)) {
            return [false, '会员购买记录不存在'];
        }

        if ($member_info['member_price'] != $notify_data['total_fee']) {
            return [false, '购买价格不一致'];
        }

        UserMemberModel::where(['order_no' => $notify_data['out_trade_no']])->update(['is_pay' => 1, 'pay_price' => $notify_data['total_fee']]);

        /**
         * 用户绑定上下级关系
         */
        $user_update['level'] = 1;
        $bind_relate    =   UserBindModel::where(['bind_user' => $member_info['user_id']])->orderBy('bind_time', 'desc')->select(['id', 'share_user', 'bind_user', 'bind_type', 'bind_time', 'expire_time'])->first();
        if (!empty($bind_relate) && $bind_relate->bind_type == UserBindModel::BIND_WEAK && Carbon::now()->timestamp < $bind_relate->expire_time) {
            $user_update['s_uid']   =   $bind_relate->share_user;
            $user_update['t_uid']   =   UserModel::where(['uid' => $bind_relate->share_user])->value('s_uid') ?? 0;
            $bind_relate->bind_type =   UserBindModel::BIND_STRONG;
            $bind_relate->save();
        }

        /**
         * 修改用户会员状态
         */
        $member_result = UserModel::where(['uid' => $member_info['user_id']])->update($user_update);
        if ($member_result) {
            return [true, $member_result];
        } else {
            return [false, '会员购买错误'];
        }
    }

    /**
     * 查询订单
     * @param string $order_number
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function notifyQuery(string $order_number)
    {
        $user_info      =   request()->post('api_user');
        $user_id        =   $user_info['user_id'];
        $wechat_config  =   Config::get('wechat');

        $pre_order['appid']     =   $wechat_config['appid'];
        $pre_order['mch_id']    =   $wechat_config['mch_id'];
        $pre_order['nonce_str'] =   Str::random(32);
        $pre_order['out_trade_no']      =   $order_number;
        $pre_order['sign']      =   wechatEncrypt($pre_order, $wechat_config['mch_key']);

        /**
         * 发起预下单请求
         */
        try {
            $query_client   =   new Client(['verify' => false, 'timeout' => 5]);
            $query_response =   $query_client->post('https://api.mch.weixin.qq.com/pay/orderquery', ['body' => xmlEncode($pre_order)]);
        } catch (\Exception $e) {
            return [false, $e->getMessage()];
        }
        $xml_data       =   $query_response->getBody()->getContents();
        $query_result   =   xmlObjectToArray(simplexml_load_string($xml_data, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NOBLANKS | LIBXML_NOERROR));

        /**
         * 预下单请求处理
         */
        if ($query_result['return_code'] == 'FAIL') {
            return [false, $query_result['return_msg']];
        } else {
            return [true, $query_result];
        }
    }


    public function notifyExpress(string $express_no)
    {

    }

}
